﻿namespace Bridge.Base.Converter
{
    using System;
    using Bridge.Base.Constructs;

    /// <summary>
    /// Class for implementing a statblock converter
    /// </summary>
    public abstract class StatblockConverter
    {
        /// <summary>
        /// Gets the <see cref="Type"/> of the <see cref="Character"/> this converter converts.
        /// </summary>
        /// <returns><see cref="Type"/> of the <see cref="Character"/> this converter converts.</returns>
        public abstract Type GetCharacterType();

        /// <summary>
        /// Gets the name of the converter.
        /// </summary>
        public abstract string Name { get; }

        /// <summary>
        /// Gets the description of the converter.
        /// </summary>
        public abstract string Description { get; }

        /// <summary>
        /// Converts a statblock into a <see cref="Character"/>
        /// </summary>
        /// <param name="input">Statblock to convert.</param>
        /// <returns><see cref="Character"/> converted.</returns>
        public abstract Character ConvertStatblock(string input);
    }

    /// <summary>
    /// Interface to call a statblock converter.
    /// </summary>
    /// <typeparam name="T">Character type that this statblock converts.</typeparam>
    public abstract class StatblockConverter<T> : StatblockConverter where T : Character
    {
        /// <summary>
        /// Gets the <see cref="Type"/> of the <see cref="Character"/> this converter converts.
        /// </summary>
        /// <returns><see cref="Type"/> of the <see cref="Character"/> this converter converts.</returns>
        public override Type GetCharacterType()
        {
            return typeof(T);
        }

        /// <summary>
        /// Converts a statblock provided by the system incoming.
        /// </summary>
        /// <param name="input">String input statblock.</param>
        /// <returns>Character converted by the Statblock converter.</returns>
        public abstract T Convert(string input);

        /// <summary>
        /// Converts a statblock into a <see cref="Character"/>
        /// </summary>
        /// <param name="input">Statblock to convert.</param>
        /// <returns><see cref="Character"/> converted.</returns>
        public override Character ConvertStatblock(string input)
        {
            return Convert(input);
        }
    }
}
